import resolver.DatabaseContentResolver
import resolver.OscarResolver
import resolver.Resolveable
import resolver.SingleLineRegExpressionResolver
import types.Hit

/**
 * this controller is used to discover chemical compounds in the given parameter
 */
class DiscoveryController {

  LookupService lookupService

  /**
   * contains all our registered resolver
   */
  private static def resolver =
  [
          //uses oscar for chemicla lookup
          new OscarResolver(0.5),

          //queryClass lookup against the database
          DatabaseContentResolver.getInstance(),

          //find combouds based on expressions
          new SingleLineRegExpressionResolver()

  ]


  def index = { }
  /**
   * process a query and returns a map containning all the found chemical names
   */
  def process = {

    //logger is added automatically by grails
    log.debug "executing a query..."

    //params are added automatically by grails
    assert (params.query != null)

    def limitConfidence = 0.5

    //if we don't have a confidence limit set we use the default
    //otherwise we assign on
    if (params.limitConfidence != null) {
      limitConfidence = params.limitConfidence
    }

    //contains the final result
    Collection<Map<Compound, ?>> result = new Vector<Map<Compound, ?>>()

    for (Hit hit: resolveContent(params.query, resolver, limitConfidence)) {

      Collection<Compound> lookedup = lookupService.lookupByHit(hit)
      for (Compound compound: lookedup) {
        result.add([compound: compound, result: compound.dbLinks,hit:hit.value,resolver:hit.getOrigin().canonicalName])
      }
    }

    log.debug("Result: ${result}")
    
    //forward to the controller
    return [result: result]
  }

  /**
   * discovers all hits for the given query
   */
  private Set<Hit> resolveContent(String query, List resolver, limitConfidence) {
    Set<Hit> result = new HashSet<Hit>()

    log.debug "confidence level was set to ${limitConfidence}"


    log.debug "executing query: ${query}"
    //we are using the resolver to find compounds
    resolver.each {Resolveable resolveable ->
      log.debug("calling: ${resolveable.class.name}")
      try {
        resolveable.activateResolver()
        resolveable.setConfidenceLevel limitConfidence

        def temp =    resolveable.resolve(query)
        log.debug("found: ${temp}")

        result.addAll(temp)
        resolveable.disactivateResolver()
      }
      catch (Exception e) {
        log.error(e.getMessage(), e
        )
      }
    }
    return result
  }
}
